package global

import (
	"database/sql"
	"fmt"
	"github.com/casbin/casbin/v2"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/os/glog"
	"github.com/robfig/cron/v3"
	"go-admin/common/config"
	"go-admin/tools"
	toolsConfig "go-admin/tools/config"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"log"
	"os"
	"time"
)

const (
	// go-admin Version Info
	Version = "1.2.0"
)

var Cfg config.Conf = config.DefaultConfig()

var GinEngine *gin.Engine
var CasbinEnforcer *casbin.SyncedEnforcer
var Eloquent *gorm.DB
var SqlDB *sql.DB

var GADMCron *cron.Cron

var (
	Source string
	Driver string
	DBName string
)

var (
	Logger        *glog.Logger
	JobLogger     *glog.Logger
	RequestLogger *glog.Logger
)

func GetDb() *gorm.DB {
	var err error
	SqlDB , err = Eloquent.DB()
	if err != nil || SqlDB == nil {
		fmt.Errorf("connect db server failed.")
		Setup()
	}
	if err := SqlDB.Ping(); err != nil {
		SqlDB.Close()
		Setup()
	}

	return Eloquent
}

func Setup() {
	Source = GetConnect()
	Logger.Info(tools.Green(Source))
	db, err := sql.Open("mysql", Source)
	if err != nil {
		Logger.Fatal(tools.Red(GetDriver()+" connect error :"), err)
	}
	db.SetMaxOpenConns(100)
	db.SetMaxIdleConns(20)
	db.SetConnMaxLifetime(time.Second * 600)
	Cfg.SetDb(&config.DBConfig{
		Driver: "mysql",
		DB:     db,
	})
	Eloquent, err = Open(db, &gorm.Config{})
	if err != nil {
		Logger.Fatal(tools.Red(GetDriver()+" connect error :"), err)
	} else {
		Logger.Info(tools.Green(GetDriver() + " connect success !"))
	}

	if Eloquent.Error != nil {
		Logger.Fatal(tools.Red(" database error :"), Eloquent.Error)
	}
	SqlDB, err = Eloquent.DB()
	if err != nil {
		Logger.Fatal(tools.Red(GetDriver()+" connect error :"), err)
	}
	Eloquent.Logger = logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{
		SlowThreshold: time.Second,
		Colorful:      true,
		LogLevel:      logger.Error,
	})
}

// 打开数据库连接
func Open(db *sql.DB, cfg *gorm.Config) (*gorm.DB, error) {
	return gorm.Open(mysql.New(mysql.Config{Conn: db}), cfg)
}

// 获取数据库连接
func GetConnect() string {
	return toolsConfig.DatabaseConfig.Source
}

func GetDriver() string {
	return toolsConfig.DatabaseConfig.Driver
}
